﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;

namespace UtilZ.Dotnet.Ex.Model
{
    /// <summary>
    /// 值域特性基类
    /// </summary>
    public abstract class RangeAbsAttribute : Attribute
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public RangeAbsAttribute()
        {

        }

    }

    /// <summary>
    /// 值域特性
    /// </summary>
    public class ValueRangeAttribute : RangeAbsAttribute
    {
        /// <summary>
        /// 最小值
        /// </summary>
        public object Min { get; private set; }

        /// <summary>
        /// 最大值
        /// </summary>
        public object Max { get; private set; }

        /// <summary>
        /// 比较类型
        /// </summary>
        public ValueRangeType RangeType { get; private set; }


        /// <summary>
        /// 构造函数-比较类型为在指定的枚举范围内
        /// </summary>
        /// <param name="min">最小值</param>
        /// <param name="max">最大值</param>
        public ValueRangeAttribute(object min, object max)
            : this(min, max, ValueRangeType.In)
        {

        }

        /// <summary>
        /// 构造函数-需指定在范围内还是在范围外
        /// </summary>
        /// <param name="min">最小值</param>
        /// <param name="max">最大值</param>
        /// <param name="rangeType">比较类型</param>
        public ValueRangeAttribute(object min, object max, ValueRangeType rangeType)
        {
            this.Min = min;
            this.Max = max;
            this.RangeType = rangeType;
        }
    }

    /// <summary>
    /// 枚举值域特性
    /// </summary>
    public class EnumRangeAttribute : RangeAbsAttribute
    {
        private readonly object[] _values;
        /// <summary>
        /// 枚举值集合
        /// </summary>
        public object[] Values
        {
            get { return _values; }
        }

        private ValueRangeType _rangeType = ValueRangeType.In;
        /// <summary>
        /// 比较类型
        /// </summary>
        public ValueRangeType RangeType
        {
            get { return _rangeType; }
            set { _rangeType = value; }
        }




        /// <summary>
        /// 构造函数,比较类型为在指定的枚举范围内(如果需要指定为其它选项,则需手指定RangeType值)
        /// </summary>
        /// <param name="values">枚举值不固定项参数集合</param>
        /// <exception cref="ArgumentNullException">枚举值集合为null或空抛出异常</exception>
        public EnumRangeAttribute(params object[] values)
            : base()
        {
            if (values == null || values.Count() == 0)
            {
                throw new ArgumentNullException(nameof(values));
            }

            this._values = values;
        }

    }

    /// <summary>
    /// 自定义值域特性
    /// </summary>
    public class CustomRangeAttribute : RangeAbsAttribute
    {
        /// <summary>
        /// 自定义值域难类型
        /// </summary>
        public Type Type { get; private set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="type">自定义值域难类型</param>
        /// <exception cref="ArgumentNullException">自定义值域难类型为null异常</exception>
        /// <exception cref="ArgumentException">自定义值域难类型未实现特定接口异常</exception>
        public CustomRangeAttribute(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (!TypeEx.IsSubInterfaceOf(type, typeof(IValueRange)))
            {
                throw new ArgumentException($"类型\"{type.FullName}\"需要实现接口\"{typeof(IValueRange).FullName}\"");
            }

            this.Type = type;
        }

    }


}
